import pymysql

"""
在开始之前，请确保已经安装好了 MySQL 数据库并保证它能正常运行，安装方式可以参考：https://setup.scrape.center/mysql。
pip install pymysql

"""

"""
  示例 1 创建数据库连接，创建数据库
"""

# db = pymysql.connect(host='localhost',user='root', password='root', port=3306)
# cursor = db.cursor() #获取 游标，用于执行sql语句
# cursor.execute('SELECT VERSION()')
# data = cursor.fetchone()  #查找第1条数据，得到版本号
# print('Database version:', data)  # Database version: ('5.7.18-log',)
# cursor.execute("CREATE DATABASE spiders DEFAULT CHARACTER SET utf8mb4") # 执行sql 创建数据库
# db.close() # 关闭连接


"""
 示例2 创建数据表
"""

# db = pymysql.connect(host='localhost', user='root', password='root', port=3306, db='spiders')
# cursor = db.cursor()
# sql = 'CREATE TABLE IF NOT EXISTS students (id VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, age INT NOT NULL, PRIMARY KEY (id))'
# cursor.execute(sql)
# db.close()


"""
 示例3 插入数据  示例1
 
 插入、更新和删除操作都是对数据库进行更改的操作，而更改操作都必须为一个事务，所以这些操作的标准写法就是：
 try:
    cursor.execute(sql)
    db.commit()
except:
    db.rollback()  一旦报错，则所有操作回滚
"""
# id = '20120002'
# user = 'Tom'
# age = 20
#
# db = pymysql.connect(host='localhost', user='root', password='root', port=3306, db='spiders')
# cursor = db.cursor()
# sql = 'INSERT INTO students(id, name, age) values(%s, %s, %s)'
# try:
#     cursor.execute(sql, (id, user, age))
#     db.commit()
# except:
#     db.rollback()
# db.close()

"""
 示例3 插入数据 示例2
 插入数据变化，插入方法无须改动，做成一个通用方法，只需要传入一个动态变化的字典就好了
"""

# data = {
#     'id': '20120002',
#     'name': 'Bob',
#     'age': 20
# }
# table = 'students'
# keys = ', '.join(data.keys())
# values = ', '.join(['%s'] * len(data))
# sql = 'INSERT INTO {table}({keys}) VALUES ({values})'.format(table=table, keys=keys, values=values)
# db = pymysql.connect(host='localhost', user='root', password='root', port=3306, db='spiders')
# cursor = db.cursor()
# try:
#    if cursor.execute(sql, tuple(data.values())):
#        print('Successful')
#        db.commit()
# except Exception as e:
#     print('Failed',e)
#     db.rollback()
# db.close()


"""
 示例4 更新数据  示例1
"""
# sql = 'UPDATE students SET age = %s WHERE name = %s'
# db = pymysql.connect(host='localhost', user='root', password='root', port=3306, db='spiders')
# cursor = db.cursor()
# try:
#    cursor.execute(sql, (25, 'Bob'))
#    print('Successful')
#    db.commit()
# except Exception as e:
#    print('Failed', e)
#    db.rollback()
# db.close()


"""
  示例5 更新数据 示例2
  部分情况下需要插入数据，但是我们关心的是会不会出现重复数据，如果出现了，我们希望更新数据而不是重复保存一次
  这里构造的 SQL 语句其实是插入语句，但是我们在后面加了 ON DUPLICATE KEY UPDATE。这行代码的意思是如果主键已经存在，就执行更新操作
  如此一来，我们就可以实现主键不存在便插入数据，存在则更新数据的功能了
"""

# data = {
#     'id': '20120001',
#     'name': 'Bob',
#     'age': 21
# }
#
# table = 'students'
# keys = ', '.join(data.keys())
# values = ', '.join(['%s'] * len(data))
#
# sql = 'INSERT INTO {table}({keys}) VALUES ({values}) ON DUPLICATE KEY UPDATE '.format(table=table, keys=keys, values=values)
# update = ','.join(["{key} = %s".format(key=key) for key in data])
# sql += update
# db = pymysql.connect(host='localhost', user='root', password='root', port=3306, db='spiders')
# cursor = db.cursor()
# try:
#     if cursor.execute(sql, tuple(data.values())*2):
#         print('Successful')
#         db.commit()
# except:
#     print('Failed')
#     db.rollback()
# db.close()


"""
 示例6 删除数据
 直接使用 DELETE 语句即可，只是需要指定要删除的目标表名和删除条件，而且仍然需要使用 db 的 commit 方法才能生效
 因为删除条件多种多样，运算符有大于、小于、等于、LIKE 等，条件连接符有 AND、OR 等，所以不再继续构造复杂的判断条件。这里直接将条件当作字符串来传递，以实现删除操作。
"""
# table = 'students'
# condition = 'age > 20'
#
# sql = 'DELETE FROM  {table} WHERE {condition}'.format(table=table, condition=condition)
# db = pymysql.connect(host='localhost', user='root', password='root', port=3306, db='spiders')
# cursor = db.cursor()
# try:
#     cursor.execute(sql)
#     db.commit()
# except:
#     db.rollback()
#
# db.close()


"""
 示例7 查询数据
 fetchone  单条、 fetchall  多条
"""
# sql = 'SELECT * FROM students WHERE age >= 20'
# db = pymysql.connect(host='localhost', user='root', password='root', port=3306, db='spiders')
# cursor = db.cursor()
# try:
#     cursor.execute(sql)
#     print('Count:', cursor.rowcount)
#     # one = cursor.fetchone()  # 游标指针会偏移，指到下一条
#     # print('One:', one)
#     results = cursor.fetchall()
#     print('Results:', results)
#     print('Results Type:', type(results))
#     for row in results:
#         print(row)
# except:
#     print('Error')
#
#

"""
 示例8 查询数据 
 fetchall 会将结果以元组形式全部返回，如果数据量很大，那么占用的开销会非常高
 推荐用:  fetchone  单条、 +while 循环查询多条数据
"""


sql = 'SELECT * FROM students WHERE age >= 20'
db = pymysql.connect(host='localhost', user='root', password='root', port=3306, db='spiders')
cursor = db.cursor()
try:
    # 这样每循环一次，指针就会偏移一条数据，随用随取，简单高效。
    cursor.execute(sql)
    print('Count:', cursor.rowcount)
    row = cursor.fetchone()
    while row:
        print('Row:', row)
        row = cursor.fetchone()
except:
    print('Error')